﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting;
using System.Web;
using System.Web.Mvc;
using DTTB.Common;
using DTTB.DTO;
using DTTB.MV2.QUANLYNHANSUTIENLUONG.Models.FormBean.PhanQuyen;
using DTTB.SERVICE;
using DTTB.MV2.QUANLYNHANSUTIENLUONG.Models.LinQ.PhanQuyen;

namespace DTTB.MV2.QUANLYNHANSUTIENLUONG.BussinessDelegate.PhanQuyen
{
    public class UsersServiceDelegate
    {
        UsersService UsersService = new UsersService();
        UsersInRolesService UsersInRolesService = new UsersInRolesService();
        PermissionsPerUsersService PermissionsPerUsersService = new PermissionsPerUsersService();
        RolesService RolesService = new RolesService();
        PathsService PathsService = new PathsService();

        PhanQuyenDataContext PhanQuyenDB = new PhanQuyenDataContext();

        DepartmentsServiceDelegate DepartmentsServiceDelegate = new DepartmentsServiceDelegate();
        JobTitlesServiceDelegate JobTitlesServiceDelegate = new JobTitlesServiceDelegate();

        public bool AddNewUsers (UsersDto usersDto)
        {
            return UsersService.AddNewUsers(usersDto);
        }

        public bool AddNewUsers (UsersDto usersDto, ref int idReturn)
        {
            return UsersService.AddNewUsers(usersDto, ref idReturn);
        }

        public bool Update(UsersDto usersDto)
        {
            return UsersService.Update(usersDto);
        }


        //getall()

        public IList<UsersDto> GetAllUsers()
        {
            return UsersService.GetAllUsers();
        }

        public IList<UsersDto> GetAllUsersActive()
        {
            return UsersService.GetAllUsersActive();
        }

        /// <summary>
        /// Tìm kiếm nhân viên theo một tiêu chí
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public IList<UsersDto> SearchUsers(int key, string value)
        {
            IList<TB_User> userList = new List<TB_User>();
            var users = from us in PhanQuyenDB.TB_Users 
                           where us.IsDelete == false && us.IsActive == true
                           select  us;
            if (key == 1) // Tìm nhân viên theo Tên nhân viên
                userList = users.Where(p => p.FullName.Contains(value.ToLower())).OrderBy(p => p.FullName).ToList();
            else if (key == 2) // Tìm nhân viên theo username
                userList = users.Where(p => p.UserName.Contains(value.ToLower())).OrderBy(p => p.FullName).ToList();
            else
            {
                userList = users.OrderBy(p => p.FullName).ToList();
            }
            return ConvertObject.ConvertEntityToDtoList<UsersDto, TB_User>(userList);
        }

        /// <summary>
        /// Lấy tất cả user trong một phòng ban xác định
        /// </summary>
        /// <param name="departmentId"></param>
        /// <returns></returns>
        public IList<UsersDto> GetAllUsersActiveInDepartment(string departmentId)
        {
            return UsersService.GetAllUsersActiveInDepartment(departmentId);
        }

        public UsersDto GetUsersById(string Id)
        {
            return UsersService.GetUsersById(Id);
        }

        public UsersDto GetIsActiveUsersById(string Id)
        {
            return UsersService.GetIsActiveUsersById(Id);
        }

        public UsersDto GetUsersByUserName(string username)
        {
            return UsersService.GetUsersByUserName(username);
        }

        public UsersDto GetUsersByUserNamePassword(string username, string password)
        {
            return UsersService.GetUsersByUserNamePassword(username, password);
        }

        /// <summary>
        /// Gets all module by Blocks in paths.
        /// </summary>
        /// <returns>A list of Object</returns>
        public IList<object> GetAllModulesInPathsByBlocks(string block)
        {
            return this.PathsService.GetAllModulesInPathsByBlocks(block);
        }
        
        /// <summary>
        /// Gets all module in paths.
        /// </summary>
        /// <returns>A list of Object</returns>
        public IList<object> GetAllModuleInPaths()
        {
            return this.PathsService.GetAllModulesInPaths();
        }
        
        /// <summary>
        /// Gets all blocks in paths.
        /// </summary>
        /// <returns>A list of Object</returns>
        public IList<object> GetAllBlocksInPaths()
        {
            return this.PathsService.GetAllBlocksInPaths();
        }

        /// <summary>
        /// Gets the paths.
        /// </summary>
        /// <returns>A list of PathsDto Objects</returns>
        public IList<PathsDto> GetPaths()
        {
            return this.PathsService.GetAllPaths();
        }


        //kiểm tra xem user có đựoc gán role hay không [ True : đựoc gán; False : Chưa đựoc gán] 
        // Dựa trên bảng RolesInUsers
        
        public bool CheckUserRole(string usersID) // viết lại hàm này nếu mở rộng thêm Group trong phần Admin
        {
            //Lấy tất cả các role thuộc về user không kể những role bị đánh dấu Isdelete == 1
            var usersInRoles = UsersInRolesService.GetUsersInRolesByUserId(usersID);

            if(usersInRoles != null && usersInRoles.Count > 0)
            {
                return true;
            }
            return false;
            
        }

        //Cải tiến
        public void CheckUserRole(IList<UsersDto> usersDtos) // viết lại hàm này nếu mở rộng thêm Group trong phần Admin
        {
            IList<UsersInRolesDto> UsersInRolesDtoList = UsersInRolesService.GetAllUsersInRoles();
            for (int i = 0; i < usersDtos.Count; i++ )
            {
                foreach (UsersInRolesDto usersInRolesDto in UsersInRolesDtoList)
                {
                    if (usersInRolesDto.UserId == usersDtos[i].ID)//Nếu user có ít nhất 1 role
                    {
                        usersDtos[i].RoleExist = true; // Đánh dấu user có Role
                        break; // dừng, ko tìm roles cho user này nữa
                    }
                }
            }
        }

        //kiểm tra xem user có đựoc gán quyền đặc biệt hay không [ True : đựoc gán; False : Chưa đựoc gán]
        // Dựa trên bảng PermissionsPerUsers
        public bool CheckSpecialPermission(string usersID)
        {
            //Lấy tất cả các permission đặc biệt(bảng TB_PermissionsPerUsers) đựoc gán thuộc về user không kể những role bị đánh dấu Isdelete == 1
            var permissionsPerUsers = PermissionsPerUsersService.GetPermissionsPerUserByUserId(usersID);

            if (permissionsPerUsers != null && permissionsPerUsers.Count > 0)
            {
                return true;
            }
            return false;
        }

        //Cải tiến
        public void CheckSpecialPermission(IList<UsersDto> usersDtos) // viết lại hàm này nếu mở rộng thêm Group trong phần Admin
        {
            IList<PermissionsPerUsersDto> PermissionsPerUsersDtoList = PermissionsPerUsersService.GetAllPermissionsPerUsers();
            for (int i = 0; i < usersDtos.Count; i++)
            {
                foreach (PermissionsPerUsersDto permissionsPerUsersDto in PermissionsPerUsersDtoList)
                {
                    if (permissionsPerUsersDto.UserId == usersDtos[i].ID)//Nếu user có ít nhất 1 role
                    {
                        usersDtos[i].SpecialPermission = true; // Đánh dấu user có Permission đặc biệt
                        break; // dừng, ko tìm Permission cho user này nữa
                    }
                }
            }

        }

        public bool Delete(string userID)
        {
          return UsersService.Delete(userID);
        }

        public UsersDto BuildNewUser(UsersForm form)
        {
            UsersDto usersDto = new UsersDto();
            
            usersDto.UserName = form.UserName;
            usersDto.FullName = form.FullName;
            usersDto.Password = EncodePasswordUser.EncodePassword(form.Password);
            usersDto.Department = form.Department;
            usersDto.JobTitle = form.JobTitle;
            usersDto.BirthDay = Convert.ToDateTime(form.BirthDay);
            usersDto.Email = form.Email;
            usersDto.Mobile = form.Mobile;
            usersDto.Sex = form.Sex;
            usersDto.LastLoginDate = DateTime.Now;
            usersDto.LastPasswordChangedDate = DateTime.Now;
            usersDto.CreateDate = DateTime.Now;
            usersDto.UpdateDate = DateTime.Now;
            usersDto.CreateBy = Convert.ToInt32(HttpContext.Current.Session["USERID"]);//  viết lại khi tiến hành edit, update
            usersDto.UpdateBy = Convert.ToInt32(HttpContext.Current.Session["USERID"]);
            usersDto.IsAdministrator = form.IsAdministrator;
            usersDto.IsActive = form.IsActive;
            usersDto.IsDelete = false;

            return usersDto;
        }

        public UsersDto BuildNewUserForEdit(UsersForm form)
        {
            UsersDto usersDto = this.GetUsersById(form.UserID);

            //usersDto.UserName = form.UserName;
            usersDto.FullName = form.FullName;
            //usersDto.Password = form.Password;
            usersDto.Department = form.Department;
            usersDto.JobTitle = form.JobTitle;
            usersDto.BirthDay = Convert.ToDateTime(form.BirthDay);
            usersDto.Email = form.Email;
            usersDto.Mobile = form.Mobile;
            usersDto.Sex = form.Sex;
            //usersDto.LastLoginDate = DateTime.Now;
            //usersDto.LastPasswordChangedDate = DateTime.Now;
            //usersDto.CreateDate = DateTime.Now;
            usersDto.UpdateDate = DateTime.Now;
            //usersDto.CreateBy = SessionDetail.USERID;
            usersDto.UpdateBy = Convert.ToInt32(HttpContext.Current.Session["USERID"]);
            usersDto.IsAdministrator = form.IsAdministrator;
            usersDto.IsActive = form.IsActive;
            //usersDto.IsDelete = false;

            return usersDto;
        }

        //public UserInJobTitleInDepartmentDto BuildNewUserInJobTitleInDepartment(UsersForm form)
        //{
        //    UserInJobTitleInDepartmentDto newDto = new UserInJobTitleInDepartmentDto();
        //    newDto.UserId = form.ID;
        //    newDto.DepartmentId = form.Department;
        //    newDto.JobTitleId = form.JobTitle;
           

        //}


        public UsersDto BuildchangePassUsers(UsersForm form)
        {
            UsersDto usersDto = new UsersDto();

            usersDto = this.GetUsersById(form.UserID);
            usersDto.Password = EncodePasswordUser.EncodePassword(form.PasswordChange);// mục đích chính của hàm này tại dòng này.
            usersDto.LastPasswordChangedDate = DateTime.Now;
            usersDto.UpdateDate = DateTime.Now;
            usersDto.UpdateBy = Convert.ToInt32(HttpContext.Current.Session["USERID"]);
            

            return usersDto;
        }

        public IList<PermissionsPerUsersDto> GetPermissonPerUsersByUserId(string currentUsersID)
        {
            try
            {
                return this.PermissionsPerUsersService.GetPermissionsPerUserByUserId(currentUsersID);
            }
            catch (System.Exception e)
            {
                throw new ServerException("Could not load all PermissionsPerUsers", e);
            }
        }

        /// <summary>
        /// Build selectList - Tiêu chí tìm kiếm nhân viên
        /// </summary>
        /// <returns></returns>
        public SelectList BuildSelectListSearchUser()
        {
            IList<object> tieuChiSearchList = new List<object>();
            tieuChiSearchList.Add(new{value = 1, Text = "Tên nhân viên"});
            tieuChiSearchList.Add(new { value = 2, Text = "Tên đăng nhập" });

            return new SelectList(tieuChiSearchList, "Value", "Text");
        }

        /// <summary>
        /// Build selectList Trống
        /// </summary>
        /// <returns></returns>
        public SelectList BuildEmtySelectList()
        {
            IList<object> emtyList = new List<object>();
            return new SelectList(emtyList, "Value", "Text");
        }


        public SelectList BuildAvaiableRoleByUserList(string userId)
        {
            IList<RolesDto> list;
            try
            {
                list = this.GetAvaiableRoleByUser(userId);
            }
            catch (Exception)
            {
                list = new List<RolesDto>();
            }

            IList<object> selectList = new List<object>();
            ////selectList.Add(new { value = 0, Text = "[ -- All Items -- ]" });
            foreach (var o in list)
            {
                selectList.Add(new { value = o.ID, Text = o.RoleName });
            }

            return new SelectList(selectList, "Value", "Text");
        }

        public IList<RolesDto> GetAllRoles()
        {
            return this.RolesService.GetAllRolesIsEnable();
        }

        public SelectList BuildRolesNotAssignedList(string userId)
        {
            IList<RolesDto> NotAssignedRoles = this.GetAllRoles();
            List<string> NotAssignedRolesId = new List<string>();
            foreach (RolesDto notAssignedRole in NotAssignedRoles)
            {
                NotAssignedRolesId.Add(notAssignedRole.ID.ToString());
            }

            IList<RolesDto> AvaiableRoles = this.GetAvaiableRoleByUser(userId);
            List<string> AvaiableRolesId = new List<string>();
            foreach (RolesDto avaiableRole in AvaiableRoles)
            {
                AvaiableRolesId.Add(avaiableRole.ID.ToString());
            }

            if (AvaiableRoles.Count > 0)
            {
                foreach (string rolesID in AvaiableRolesId)
                {
                    if (NotAssignedRolesId.Contains(rolesID))
                    {
                        NotAssignedRolesId.Remove(rolesID);
                    }
                }
            }

            IList<RolesDto> newNotAssignedRoles = new List<RolesDto>();

            foreach (string notAssignedRolesID in NotAssignedRolesId)
            {
                newNotAssignedRoles.Add(this.RolesService.GetRolesByID(notAssignedRolesID.ToString()));
            }

            IList<object> selectList = new List<object>();
            foreach (var o in newNotAssignedRoles)
            {
                selectList.Add(new { value = o.ID, Text = o.RoleName });
            }

            return new SelectList(selectList, "Value", "Text");
        }

        public IList<RolesDto> GetAvaiableRoleByUser(string userId)
        {
            IList<RolesDto> rolesDtos = new List<RolesDto>();

            IList<UsersInRolesDto> usersInRolesDtos = this.UsersInRolesService.GetUsersInRolesByUserId(userId);

            foreach (UsersInRolesDto usersInRolesDto in usersInRolesDtos)
            {
                try
                {
                    RolesDto rolesDto = this.RolesService.GetRolesByID(usersInRolesDto.RoleId.ToString());
                    rolesDtos.Add(rolesDto);
                }
                catch (System.Exception e)
                {
                    continue;
                }
            }

            return rolesDtos;
        }

        public void UpdateRolesPerUsers(IList<UsersInRolesDto> usersInRolesDtos, string usersID)
        {
            this.UsersService.UpdateRolesPerUsers(usersInRolesDtos, usersID);
        }

        public void UpdatePermissonPerUsers(IList<PermissionsPerUsersDto> permissionsPerUserDtos, string usersID)
        {
            this.UsersService.UpdatePermissonPerUsers(permissionsPerUserDtos, usersID);
        }

        public void BuildSelectListForUsersForm(UsersForm form)
        {
            form.DepartmentsSelectList = DepartmentsServiceDelegate.BuildDepartmentSelectList();
            form.JobTitlesSelectList = JobTitlesServiceDelegate.BuildJobTitleSelectList();
            form.TieuChiSearchDropDownList = BuildSelectListSearchUser();
        }


    }
}
